﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Taxonomy;
using Microsoft.SharePoint.Administration;
using System.Linq;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Globalization;
using System.IO;
using System.Web.UI;

namespace ExporttoExcelinMacOS.Layouts
{
    public partial class ExporttoExcel : LayoutsPageBase
    {
        HttpResponse _exportResponse;
        bool _isErrorOccured = false;

        protected void Page_Init(object sender, EventArgs e)
        {
            _exportResponse = Response;
            // Get view and list guids from the request.
            Guid listGUID = new Guid(Request["ListGuid"].ToString());
            Guid viewGUID = new Guid(Request["ViewGuid"].ToString());

            if (Request["IDselected"].ToString() != "")
            {

                var listItemsID = Request["IDselected"].ToString().Split(new Char[] { ',' });
                ExportSelectedItemsToExcel(listGUID, viewGUID, listItemsID);
            }
            else
            {
                var listItemsID = new String[0];
                ExportSelectedItemsToExcel(listGUID, viewGUID, listItemsID);
            }





        }
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        public void ExportSelectedItemsToExcel(Guid listID, Guid listViewID, String[] selectedlistids)
        {

            try
            {
                SPList list = SPContext.Current.Web.Lists[listID];
                SPView listView = list.Views[listViewID];

                //create the table 

                var exportListTable = new HtmlTable { Border = 1, CellPadding = 3, CellSpacing = 3 };

                HtmlTableCell htmlcell;


                var htmlrow = new HtmlTableRow();
                SPViewFieldCollection viewHeaderFields = listView.ViewFields;
                for (var index = 0; index < viewHeaderFields.Count; index++)
                    foreach (
                        SPField field in
                            listView.ParentList.Fields.Cast<SPField>().Where(
                                field => field.InternalName == viewHeaderFields[index]))
                    {
                        if (!field.Hidden)
                        {
                            htmlcell = new HtmlTableCell
                            {
                                BgColor = "blue",
                                InnerHtml = field.Title.ToString(CultureInfo.InvariantCulture)
                            };
                            htmlrow.Cells.Add(htmlcell);
                        }
                        break;
                    }
                exportListTable.Rows.Add(htmlrow);

                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Added header :");

                //   Add rows in HTML table based on the fields in view.
                #region when there is items selected
                if (selectedlistids != null && selectedlistids.Count() > 0)
                {
                    foreach (string id in selectedlistids.Where(id => !String.IsNullOrEmpty(id)))
                    {
                        htmlrow = new HtmlTableRow();

                        SPListItem item = list.GetItemById(Convert.ToInt32(id));
                        SPViewFieldCollection viewFields = listView.ViewFields;
                        for (var i = 0; i < viewFields.Count; i++)
                        {
                            foreach (SPField field in listView.ParentList.Fields.Cast<SPField>().Where(field => field.InternalName == viewFields[i]))
                            {
                                if (!field.Hidden)
                                {
                                    htmlcell = new HtmlTableCell();
                                    htmlcell = new HtmlTableCell();
                                    if (item[field.InternalName] != null)
                                    {

                                        if ((string.CompareOrdinal(field.TypeAsString, "TaxonomyFieldType") == 0) || (string.CompareOrdinal(field.TypeAsString, "TaxonomyFieldTypeMulti") == 0))
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromTaxonomyField(field, item) != "") || (GetValuesFromTaxonomyField(field, item) != null)) ? GetValuesFromTaxonomyField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Lookup)
                                        {
                                            // call the method to get lookup field 
                                            htmlcell.InnerHtml = ((GetValuesFromLookupField(field, item) != "") || (GetValuesFromLookupField(field, item) != null)) ? GetValuesFromLookupField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.User)
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromUserField(field, item) != "") || (GetValuesFromUserField(field, item) != null)) ? GetValuesFromUserField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Invalid)
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromInvalidTypeField(field, item) != "") || (GetValuesFromInvalidTypeField(field, item) != null)) ? GetValuesFromInvalidTypeField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Calculated)
                                        {
                                            var cf = (SPFieldCalculated)field;
                                            htmlcell.InnerHtml = ((cf.GetFieldValueAsText(item[field.InternalName]) != "") || (cf.GetFieldValueAsText(item[field.InternalName]) != null)) ? cf.GetFieldValueAsText(item[field.InternalName]) : "";
                                        }
                                        else
                                        {
                                            htmlcell.InnerHtml = ((Convert.ToString(item[field.InternalName]) != "") || Convert.ToString(item[field.InternalName]) != null) ? item[field.InternalName].ToString() : "";
                                        }
                                    }
                                    else
                                    {
                                        htmlcell.InnerHtml = String.Empty;
                                    }
                                    htmlrow.Cells.Add(htmlcell);
                                }
                                break;
                            }
                        }
                        exportListTable.Rows.Add(htmlrow);
                        SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Added this item to export only selected :" + "Name:" + item.Name + "Title:" + item.Title + "Title:" + item.ID);

                    }

                }
                #endregion
                #region When none of the item is selected
                else
                {
                    var query = new SPQuery();
                    query.Query = listView.Query;
                    SPListItemCollection GetItems = list.GetItems(query);

                    foreach (SPListItem item in GetItems)
                    {
                        htmlrow = new HtmlTableRow();


                        SPViewFieldCollection viewFields = listView.ViewFields;
                        for (var i = 0; i < viewFields.Count; i++)
                        {
                            foreach (SPField field in listView.ParentList.Fields.Cast<SPField>().Where(field => field.InternalName == viewFields[i]))
                            {
                                if (!field.Hidden)
                                {
                                    htmlcell = new HtmlTableCell();
                                    if (item[field.InternalName] != null)
                                    {

                                        if ((string.CompareOrdinal(field.TypeAsString, "TaxonomyFieldType") == 0) || (string.CompareOrdinal(field.TypeAsString, "TaxonomyFieldTypeMulti") == 0))
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromTaxonomyField(field, item) != "") || (GetValuesFromTaxonomyField(field, item) != null)) ? GetValuesFromTaxonomyField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Lookup)
                                        {
                                            // call the method to get lookup field 
                                            htmlcell.InnerHtml = ((GetValuesFromLookupField(field, item) != "") || (GetValuesFromLookupField(field, item) != null)) ? GetValuesFromLookupField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.User)
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromUserField(field, item) != "") || (GetValuesFromUserField(field, item) != null)) ? GetValuesFromUserField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Invalid)
                                        {
                                            htmlcell.InnerHtml = ((GetValuesFromInvalidTypeField(field, item) != "") || (GetValuesFromInvalidTypeField(field, item) != null)) ? GetValuesFromInvalidTypeField(field, item) : "";
                                        }
                                        else if (field.Type == SPFieldType.Calculated)
                                        {
                                            var cf = (SPFieldCalculated)field;
                                            htmlcell.InnerHtml = ((cf.GetFieldValueAsText(item[field.InternalName]) != "") || (cf.GetFieldValueAsText(item[field.InternalName]) != null)) ? cf.GetFieldValueAsText(item[field.InternalName]) : "";
                                        }
                                        else
                                        {
                                            htmlcell.InnerHtml = ((Convert.ToString(item[field.InternalName]) != "") || Convert.ToString(item[field.InternalName]) != null) ? item[field.InternalName].ToString() : "";
                                        }
                                    }
                                    else
                                    {
                                        htmlcell.InnerHtml = String.Empty;
                                    }
                                    htmlrow.Cells.Add(htmlcell);
                                }
                                break;
                            }
                            exportListTable.Rows.Add(htmlrow);
                            SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Added this item to export whole list :" + "Name:" + item.Name + "Title:" + item.Title + "Title:" + item.ID);
                        }
                    }
                #endregion


                }

                // Write the HTML table contents to response as excel file
                string doctitle = list.Title + "_" + Convert.ToString(DateTime.Now.ToString("dd/MM/yyyy"));
                using (var sw = new StringWriter())
                {
                    using (var htw = new HtmlTextWriter(sw))
                    {
                        exportListTable.RenderControl(htw);
                        _exportResponse.Clear();
                        _exportResponse.ContentType = "application/vnd.ms-excel";
                        _exportResponse.AddHeader("content-disposition", string.Format("attachment; filename={0}", doctitle + ".xls"));
                        _exportResponse.Cache.SetCacheability(HttpCacheability.NoCache);
                        _exportResponse.ContentEncoding = System.Text.Encoding.Unicode;
                        _exportResponse.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
                        _exportResponse.Write(sw.ToString());
                        _exportResponse.End();
                    }
                }
            }
            catch (System.Threading.ThreadAbortException exception)
            {
                // Do nothing on thread abort exception.
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, exception.Message);
            }
            catch (Exception ex)
            {
                _isErrorOccured = true;
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message);
            }
            finally
            {
                if (_isErrorOccured)
                {
                    SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Exported with errors");
                }

            }

        }
        private string GetValuesFromInvalidTypeField(SPField field, SPListItem item)
        {
            string invalidtypefieldvalue = string.Empty;
            try
            {
                var lookupField = (SPFieldLookup)field;

                if (lookupField.AllowMultipleValues)
                {
                    var values = item[field.InternalName] as SPFieldLookupValueCollection;
                    if (values != null)
                        invalidtypefieldvalue = values.Aggregate(invalidtypefieldvalue, (current, value) => current + value.LookupValue.ToString(CultureInfo.InvariantCulture) + "; ");
                }
                else
                {
                    var fieldValue = new SPFieldLookupValue(item[field.InternalName].ToString());
                    invalidtypefieldvalue = fieldValue.LookupValue.ToString(CultureInfo.InvariantCulture);
                }
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Exception:", ex.Message);
            }
            return invalidtypefieldvalue;
        }
        public String GetValuesFromLookupField(SPField field, SPItem item)
        {

            SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Look up Field");
            string lookupfieldvalue = string.Empty;
            try
            {
                var lookupField = (SPFieldLookup)field;

                if (lookupField.AllowMultipleValues)
                {
                    var values = item[field.InternalName] as SPFieldLookupValueCollection;
                    if (values != null)
                        lookupfieldvalue = values.Aggregate(lookupfieldvalue, (current, value) => current + value.LookupValue.ToString(CultureInfo.InvariantCulture) + "; ");
                }
                else
                {
                    var fieldValue = new SPFieldLookupValue(item[field.InternalName].ToString());
                    lookupfieldvalue = fieldValue.LookupValue.ToString(CultureInfo.InvariantCulture);
                }

                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Look up Field value" + lookupfieldvalue);

            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Look up Field exception" + ex.Message);
            }
            return lookupfieldvalue;
        }
        public String GetValuesFromUserField(SPField field, SPItem item)
        {
            var userfieldvalue = string.Empty;
            try
            {
                var userFieldValueCol = new SPFieldUserValueCollection(SPContext.Current.Web, item[field.InternalName].ToString());
                userfieldvalue = userFieldValueCol.Select(singlevalue => singlevalue.ToString().Split('#')).Aggregate(userfieldvalue, (current, userValue) => current + userValue[1] + "; ");
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Exception:", ex.Message);
            }

            return userfieldvalue;
        }
        public String GetValuesFromTaxonomyField(SPField field, SPItem item)
        {
            var txField = field as TaxonomyField;
            var taxonomyfieldvalue = string.Empty;
            try
            {
                if (txField != null)
                {
                    if (txField.AllowMultipleValues)
                    {
                        var taxfieldValColl = (item[field.InternalName] as TaxonomyFieldValueCollection);
                        if (taxfieldValColl != null)
                            taxonomyfieldvalue = taxfieldValColl.Aggregate(taxonomyfieldvalue, (current, singlevalue) => current + singlevalue.Label.ToString(CultureInfo.InvariantCulture) + "; ");
                    }
                    else
                    {
                        var singlevalue = item[field.InternalName] as TaxonomyFieldValue;
                        if (singlevalue != null) taxonomyfieldvalue = taxonomyfieldvalue + singlevalue.Label.ToString(CultureInfo.InvariantCulture);
                    }
                }
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Excel Export", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Exception:", ex.Message);
            }
            return taxonomyfieldvalue;
        }
    }
}
